package com.knife.interfaces.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.knife.common.constants.BaseConstants;
import com.knife.common.entity.BaseDto;
import com.knife.common.utils.EntityFieldUtil;
import com.knife.interfaces.constants.KnifeInterfaceCodeEnum;
import com.knife.interfaces.constants.KnifeInterfaceLogDirection;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.Assert;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * 接口日志实体
 *
 * @author: tianhao.luo@hand-china.com 2021/6/30  下午12:47
 */
@EqualsAndHashCode(callSuper = true)
@Table(name = "HITF_INTERFACE_LOG")
@Entity
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@DynamicInsert
@DynamicUpdate
@Data
public class KnifeInterfaceLogRecord extends BaseDto {

    public static final String FIELD_ID = "id";
    public static final String FIELD_INVOKE_KEY = "invokeKey";
    public static final String FIELD_INTERFACE_URL = "interfaceUrl";
    public static final String FIELD_INTERFACE_REQUEST_METHOD = "interfaceRequestMethod";
    public static final String FIELD_INTERFACE_REQUEST_TIME = "interfaceRequestTime";
    public static final String FIELD_INTERFACE_RESPONSE_TIME = "interfaceResponseTime";
    public static final String FIELD_INTERFACE_RESPONSE_CODE = "interfaceResponseCode";
    public static final String FIELD_INTERFACE_RESPONSE_STATUS = "interfaceResponseStatus";
    public static final String FIELD_REQUEST_METHOD = "requestMethod";
    public static final String FIELD_REQUEST_TIME = "requestTime";
    public static final String FIELD_IP = "ip";
    public static final String FIELD_REFERER = "referer";
    public static final String FIELD_USER_AGENT = "userAgent";
    public static final String FIELD_INTERFACE_REQ_HEADER_PARAM = "interfaceReqHeaderParam";
    public static final String FIELD_INTERFACE_REQ_URL_PARAM = "interfaceReqUrlParam";
    public static final String FIELD_INTERFACE_REQ_URL_PARAM_FILE_ID = "interfaceReqUrlParamFileId";
    public static final String FIELD_INTERFACE_REQ_BODY_PARAM = "interfaceReqBodyParam";
    public static final String FIELD_INTERFACE_REQ_BODY_PARAM_FILE_ID = "interfaceReqBodyParamFileId";
    public static final String FIELD_INTERFACE_RESP_CONTENT = "interfaceRespContent";
    public static final String FIELD_INTERFACE_RESP_CONTENT_FILE_ID = "interfaceRespContentFileId";

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    /**
     * 日志主键(uuid)
     */
    private String invokeKey;
    /**
     * 访问的接口地址
     */
    private String interfaceUrl;

    /**
     * 接口请求方式
     */
    private String interfaceRequestMethod;
    /**
     * 接口触发请求开始时间
     */
    @JsonFormat(pattern = BaseConstants.Pattern.DATETIME)
    @DateTimeFormat(pattern = BaseConstants.Pattern.DATETIME)
    private Date interfaceRequestTime;
    /**
     * 接口收到响应的时间
     */
    @JsonFormat(pattern = BaseConstants.Pattern.DATETIME)
    @DateTimeFormat(pattern = BaseConstants.Pattern.DATETIME)
    private Date interfaceResponseTime;
    /**
     * 接口响应code,如200
     */
    private String interfaceResponseCode;
    /**
     * 接口响应状态,如success
     */
    private String interfaceResponseStatus;
    /**
     * 触发调用接口的方法,如exchange
     */
    private String requestMethod;
    /**
     * 调用请求的时间
     */
    private Long requestTime;
    /**
     * 发起的ip
     */
    private String ip;
    /**
     * 请求头数据
     */
    private String referer;
    /**
     * 请求头中的数据
     */
    private String userAgent;
    /**
     * 请求头参数(超长被截断)
     */
    private String interfaceReqHeaderParam;
    /**
     * 请求url参数(超长不截断)
     */
    private String interfaceReqUrlParam;
    /**
     * 请求url文件id
     */
    private String interfaceReqUrlParamFileId;
    /**
     * 请求体参数(超长不截断),存放在文件中
     */
    private String interfaceReqBodyParam;
    /**
     * 请求体文件id
     */
    private String interfaceReqBodyParamFileId;
    /**
     * 请求响应体(超长不截断),存放在文件中
     */
    private String interfaceRespContent;
    /**
     * 请求响应体文件id
     */
    private String interfaceRespContentFileId;



    /**
     * 该构造方法不支持接口编码及描述的记录，已经过时了
     *
     * @param interfaceRequestTime       请求发起时间
     * @param knifeInterfaceLogDirection 请求方向
     */
    @Deprecated
    public KnifeInterfaceLogRecord(@NotNull Date interfaceRequestTime, @NotNull KnifeInterfaceLogDirection knifeInterfaceLogDirection) {
        Assert.notNull(interfaceRequestTime, "调用接口必须有开始时间");
        this.interfaceRequestTime = interfaceRequestTime;
        // 接口调用方向向外请求则为out向内请求则为in
        this.setAttribute1(knifeInterfaceLogDirection.name());
    }

    /**
     * 构造接口日志
     *
     * @param interfaceRequestTime       请求发起时间
     * @param knifeInterfaceLogDirection 请求方向
     * @param knifeInterfaceCodeEnum     接口编码和接口描述
     */
    public KnifeInterfaceLogRecord(@NotNull Date interfaceRequestTime,
                                   @NotNull KnifeInterfaceLogDirection knifeInterfaceLogDirection,
                                   KnifeInterfaceCodeEnum knifeInterfaceCodeEnum) {
        Assert.notNull(interfaceRequestTime, "调用接口必须有开始时间");
        this.interfaceRequestTime = interfaceRequestTime;
        // 接口调用方向向外请求则为out向内请求则为in
        this.setAttribute1(knifeInterfaceLogDirection.name());
        // 添加描述
        this.setAttribute2(knifeInterfaceCodeEnum.getInterfaceCode());
        this.setAttribute3(knifeInterfaceCodeEnum.getDescription());
    }

    public KnifeInterfaceLogRecord() {
    }

}
